require "import"
import "com.androlua.*"
import "android.widget.*"
layout={
GridView,
id="grid",
numColumns=2,
layout_width="fill",
layout_height="fill"
}
items={"ghi âm", "chuyển đổi định dạng âm thanh", "máy nghe nhạc"}
dlg=LuaDialog(this)
dlg.View=loadlayout(layout)
grid.adapter=SingleLineAdapter(service, String(items))
dlg.setTitle ("Audio Hub")
dlg.show()
grid.onItemClick=function(l,v)
dlg.dismiss()
task(100, function()
if v.text == "click vào đây để tham gia nhóm cộng đồng jieshuo việt nam nhé!" then service.openUrl(
"https://t.me/+4MDkmPC3YIcxODRl"
)
elseif v.text == "ghi âm" then
--listo grabador en formato wav
if RFirst then
RFirst = 1;
else
RFirst = 2;
end
if RFirst == 2 then
RCount = 1;
end
if RFirst == 1 then
RCount = RCount+1;
end
if RCount > 2 then
RCount = 1
end
switch RCount 
case 1
require "import"
import "android.content.Context"
import "android.os.Vibrator"
import "java.io.FileOutputStream"
import "java.io.OutputStreamWriter"
import "java.io.BufferedReader"
import "java.io.InputStreamReader"
import "android.media.MediaRecorder"
import "android.media.MediaScannerConnection"
import "java.io.File"
import "java.io.FileInputStream"
import "java.text.SimpleDateFormat"
import "java.util.Date"
import "android.content.ContentValues"
import "android.provider.MediaStore"
local folderPath = "/storage/emulated/0/Audio Hub"
local folder = File(folderPath)

if not folder.exists() then
  local success = folder.mkdirs()

  if success then
    service.asyncSpeak("tập tin sẽ được lưu tại thư mục" .. folderPath)
  else
    service.asyncSpeak("Không thể tạo thư mục tại:" .. folderPath)
  end
end


counterFile = File("/storage/emulated/0/orden.txt")
counterFile.delete()
local isRecording = false
local folderName = "Audio Hub"
local folderPath = "/storage/emulated/0/" .. folderName
local counterFilePath = "/storage/emulated/0/contador.txt"
local dateFormat = SimpleDateFormat("HH_mm_ss", Locale.getDefault())
local currentTime = dateFormat.format(Date())
local outputFile = folderPath .. "/recorded_audio_" .. currentTime .. ".wav"

local function createCounterFile()
    local file = File(counterFilePath)
    if not file.exists() then
        file.createNewFile()
        local outputStream = FileOutputStream(file)
        local writer = OutputStreamWriter(outputStream)
        writer.write("1")
        writer.close()
        outputStream.close()
    end
end

local function readFileContent(file)
    local content = ""
    local bufferedReader = BufferedReader(InputStreamReader(FileInputStream(file)))
    local line = bufferedReader.readLine()
    while line do
        content = content .. line
        line = bufferedReader.readLine()
    end
    bufferedReader.close()
    return content
end

local function getCounter()
    createCounterFile()
    local file = File(counterFilePath)
    local content = readFileContent(file)
    local counter = tonumber(content)
    return counter
end

local function updateCounter(counter)
    local file = File(counterFilePath)
    local outputStream = FileOutputStream(file)
    local writer = OutputStreamWriter(outputStream)
    writer.write(tostring(counter))
    writer.close()
    outputStream.close()
end

local function getNextRecordingNumber()
    local counter = getCounter()
    updateCounter(counter + 1)
    return counter
end

function stopRecording()
    if isRecording then
        mediaRecorder.stop()
        mediaRecorder.release()
        mediaRecorder = nil
        isRecording = false

        MediaScannerConnection.scanFile(this, {outputFile}, nil, nil)

        local values = ContentValues()
        values.put(MediaStore.MediaColumns.DATA, outputFile)
        values.put(MediaStore.MediaColumns.TITLE, "Grabación de audio")
        values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/wav")
        this.getContentResolver().insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values)
    end
end

local function startRecording()
    if not isRecording then
        mediaRecorder = MediaRecorder()
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC)
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS)
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
        mediaRecorder.setAudioEncodingBitRate(320000)
        mediaRecorder.setAudioSamplingRate(48000)
        
        local recordingNumber = getNextRecordingNumber()
        local recordingFile = File(folderPath, "ghi âm_" .. recordingNumber .. ".wav")
        outputFile = recordingFile.getAbsolutePath()
        
        mediaRecorder.setOutputFile(outputFile)
        mediaRecorder.prepare()
        mediaRecorder.start()
        isRecording = true
    end
end

startRecording()
local context = activity or service
local vibrator = context.getSystemService(Context.VIBRATOR_SERVICE)
if vibrator.hasVibrator() then
    vibrator.vibrate(100)
end
return true
case 2
stopRecording()
service.asyncSpeak("đã dừng ghi âm")
require "import"
import "android.content.Context"
import "android.os.Vibrator"
local context = activity or service
local vibrator = context.getSystemService(Context.VIBRATOR_SERVICE)
if vibrator.hasVibrator() then
    vibrator.vibrate(200)
end
return true
end
return true
elseif v.text == "chuyển đổi định dạng âm thanh" then
require "import"
import "java.io.FileOutputStream"
import "java.io.OutputStreamWriter"
import "java.io.BufferedReader"
import "java.io.InputStreamReader"
import "java.io.File"
import "java.io.FileInputStream"
import "java.text.SimpleDateFormat"
import "java.util.Date"
import "android.content.ContentValues"
import "android.media.MediaMuxer"
import "android.media.MediaFormat"
import "android.content.*"
import "android.content.pm.PackageManager"
import "android.net.Uri"
import "android.view.View"
import "android.widget.*"
import "android.content.Intent"
import "android.media.MediaPlayer"
import "android.content.Context"
import "android.os.Vibrator"
import "java.lang.reflect.Array"
import "java.lang.System"
import "android.os.Environment"
import "android.media.AudioManager"
import "java.io.File"
import "android.os.Environment"
import "android.widget.ArrayAdapter"
import "android.content.Context"
import "android.os.Vibrator"
import "android.widget.*"
import "com.androlua.*"
 context = activity or service
 vibrator = context.getSystemService(Context.VIBRATOR_SERVICE)
vibrator.vibrate(100)
--marcador bibliotecas
if isPlaying then
mediaPlayer.stop()
mediaPlayer.reset()
isPlaying = false
currentSoundFilePath = nil
end
currentSoundIndex = 0
 externalPath = Environment.getExternalStorageDirectory().getAbsolutePath()
 soundFolderPath = externalPath .. "/Audio Hub/"
 soundFolder = File(soundFolderPath)
 soundFiles = soundFolder.listFiles()
 soundFilePaths = {}
if soundFiles ~= nil then
     soundFileCount = Array.getLength(soundFiles)
    if soundFileCount > 0 then
         soundFileCreationTimes = {}
        for i = 0, soundFileCount - 1 do
             soundFile = soundFiles[i]
             soundFilePath = soundFile.getAbsolutePath()
             fileName = soundFile.getName()
             creationTime = soundFile.lastModified()
            table.insert(soundFileCreationTimes, { filePath = soundFilePath, displayName = fileName, creationTime = creationTime })
        end
        table.sort(soundFileCreationTimes, function(a, b)
            return a.creationTime < b.creationTime
        end)
        for i = 1, #soundFileCreationTimes do
             soundFile = soundFileCreationTimes[i]
            table.insert(soundFilePaths, { filePath = soundFile.filePath, displayName = soundFile.displayName })
        end
    else
        service.asyncSpeak("Không tìm thấy tệp âm thanh nào trong thư mục:" .. soundFolderPath)
        return false
    end
else
    service.asyncSpeak("Không thể truy cập thư mục:" .. soundFolderPath)
    return false
end
 adapterItems = {}
 isLongPress = false
 mediaPlayer = MediaPlayer()
 function cargarArchivos()
  soundFilePaths = {}
   soundFolderPath = externalPath .. "/Audio Hub/"
   soundFolder = File(soundFolderPath)
   soundFiles = soundFolder.listFiles()
  if soundFiles ~= nil then
     soundFileCount = Array.getLength(soundFiles)
    if soundFileCount > 0 then
       soundFileCreationTimes = {}
      for i = 0, soundFileCount - 1 do
         soundFile = soundFiles[i]
         soundFilePath = soundFile.getAbsolutePath()
         fileName = soundFile.getName()
         creationTime = soundFile.lastModified()
        table.insert(soundFileCreationTimes, { filePath = soundFilePath, displayName = fileName, creationTime = creationTime })
      end
      table.sort(soundFileCreationTimes, function(a, b)
        return a.creationTime < b.creationTime
      end)
      for i = 1, #soundFileCreationTimes do
         soundFile = soundFileCreationTimes[i]
        table.insert(soundFilePaths, { filePath = soundFile.filePath, displayName = soundFile.displayName })
      end
      grid.adapter.clear()
      for i, fileData in ipairs(soundFilePaths) do
        grid.adapter.add(fileData.displayName)
      end
      grid.adapter.notifyDataSetChanged()
    else
      service.asyncSpeak("Không tìm thấy tệp âm thanh nào trong thư mục:" .. soundFolderPath)
    end
  else
    service.asyncSpeak("Không thể truy cập thư mục:" .. soundFolderPath)
  end
end
 function renameItem(position)
   fileData = soundFilePaths[position + 1]
   file = File(fileData.filePath)
   fileName, fileExtension = string.match(fileData.displayName, "(.-)(%.%w+)$") -- Obtener el nombre y la extensión del archivo
   renameDialog = LuaDialog(context)
  renameDialog.setTitle("Đổi tên tập tin")
   input = EditText(context)
  input.setText(fileName)
  renameDialog.setView(input)
  renameDialog.setPositiveButton("đồng ý", DialogInterface.OnClickListener {
    onClick = function(dialog, which)
       newFileName = tostring(input.getText())
       newFilePath = file.getParent() .. "/" .. newFileName .. fileExtension
       newFile = File(newFilePath)
      if file.renameTo(newFile) then
        fileData.displayName = newFileName .. fileExtension
        adapterItems[position + 1] = fileData -- Actualizar el elemento en adapterItems
        grid.adapter.clear()
        for i, fileData in ipairs(soundFilePaths) do
          grid.adapter.add(fileData.displayName)
        end
        grid.adapter.notifyDataSetChanged()
        service.asyncSpeak("Đã đổi tên tệp thành công.")
        -- dlg.dismiss()
guardarOrden()
cargarOrden()
cargarArchivos()
      else
        service.asyncSpeak("Lỗi khi đổi tên tệp.")
      end
      dialog.dismiss()
    end
  })
  renameDialog.setNegativeButton("hủy", DialogInterface.OnClickListener {
    onClick = function(dialog, which)
      dialog.dismiss()
    end
  })
  renameDialog.show()
end
function cargarOrden()
     externalPath = Environment.getExternalStorageDirectory().getAbsolutePath()
     ordenFilePath = externalPath .. "/orden.txt"
     ordenFile = File(ordenFilePath)
    if ordenFile.exists() then
        soundFilePaths = {}
         inputStream = FileInputStream(ordenFile)
         reader = BufferedReader(InputStreamReader(inputStream))
         line = reader.readLine()
        while line ~= nil do
             filePath, displayName = line:match("([^,]+),([^,]+)")
            table.insert(soundFilePaths, { filePath = filePath, displayName = displayName })
            line = reader.readLine()
        end
        reader.close()
    end
end
cargarOrden()
 adapterItems = {}
for i, fileData in ipairs(soundFilePaths) do
    table.insert(adapterItems, fileData.displayName)
end
 function shareFile(position)
     selectedSoundFilePath = soundFilePaths[position + 1].filePath
    service.shareFile(selectedSoundFilePath)
guardarOrden()
dlg.dismiss()
end
 function deleteItem(position)
     fileData = soundFilePaths[position + 1]
     file = File(fileData.filePath)
     confirmationDialog = LuaDialog(context)
    confirmationDialog.setTitle("xóa")
    confirmationDialog.setMessage("Bạn có chắc chắn muốn xóa tệp này không?")
    confirmationDialog.setPositiveButton("xóa", DialogInterface.OnClickListener {
        onClick = function(dialog, which)
            file.delete()
            table.remove(soundFilePaths, position + 1)
            service.asyncSpeak("Đã xóa tệp thành công.")
         adapter = grid.adapter
        adapter.clear()
        for i, fileData in ipairs(soundFilePaths) do
            adapter.add(fileData.displayName)
        end
        adapter.notifyDataSetChanged()
        guardarOrden()
cargarOrden()
        end
    })
    confirmationDialog.setNegativeButton("hủy", DialogInterface.OnClickListener {
        onClick = function(dialog, which)
            dialog.dismiss()
        end
    })
    confirmationDialog.show()
end
 function deleteFiles()
     confirmationDialog = LuaDialog(context)
    confirmationDialog.setTitle("xóa các tập tin")
    confirmationDialog.setMessage("Bạn có chắc chắn muốn xóa tất cả các tập tin?")
    confirmationDialog.setPositiveButton("xóa", DialogInterface.OnClickListener {
        onClick = function(dialog, which)
            for i, fileData in ipairs(soundFilePaths) do
                 file = File(fileData.filePath)
                file.delete()
            end
             counterFile = File("/storage/emulated/0/contador.txt")
            counterFile.delete()
 counter3File = File("/storage/emulated/0/orden.txt")
counter3File.delete()
            soundFilePaths = {}
            service.asyncSpeak("Các tập tin đã được xóa thành công.")
dlg.dismiss()
        end
    })
    confirmationDialog.setNegativeButton("hủy", DialogInterface.OnClickListener {
        onClick = function(dialog, which)
            dialog.dismiss()
        end
    })
    confirmationDialog.show()
end
 function closeDialog()
    if isPlaying then
        mediaPlayer.stop()
        mediaPlayer.reset()
        isPlaying = false
        currentSoundFilePath = nil
    end
guardarOrden()
dlg.dismiss()
end
 function subir(position)
    if position > 0 then
         fileData = table.remove(soundFilePaths, position + 1)
        table.insert(soundFilePaths, position, fileData)
         adapter = grid.adapter
        adapter.clear()
        for i, fileData in ipairs(soundFilePaths) do
            adapter.add(fileData.displayName)
        end
        adapter.notifyDataSetChanged()
        guardarOrden()
    end
end
 function bajar(position)
    if position < #soundFilePaths - 1 then
         fileData = table.remove(soundFilePaths, position + 1)
        table.insert(soundFilePaths, position + 2, fileData)
         adapter = grid.adapter
        adapter.clear()
        for i, fileData in ipairs(soundFilePaths) do
            adapter.add(fileData.displayName)
        end
        adapter.notifyDataSetChanged()
        guardarOrden() -- Guardar el nuevo orden
    end
end
 function combineFiles()
     combinedFileName = "audio"
     combinedFileExtension = ".mp3" 
     combinedFilePath = soundFolderPath .. combinedFileName .. combinedFileExtension
combinedFile = io.open(combinedFilePath, "wb")
    if combinedFile then
        for i, fileData in ipairs(soundFilePaths) do
             soundFile = io.open(fileData.filePath, "rb")
            if soundFile then
                 data = soundFile:read("*a")
                combinedFile:write(data)
                soundFile:close()
            else
                service.asyncSpeak("Lỗi khi mở tệp:" .. fileData.filePath)
            end
        end
        combinedFile:close()
service.asyncSpeak("đã chuyển đổi")
        grid.adapter.clear()
        for i, fileData in ipairs(soundFilePaths) do
            grid.adapter.add(fileData.displayName)
        end
        grid.adapter.notifyDataSetChanged()
        guardarOrden() -- Guardar el nuevo orden
        cargarOrden()
        cargarArchivos()
    else
        service.asyncSpeak("không thể chuyển đổi")
    end
end
function guardarOrden()
     externalPath = Environment.getExternalStorageDirectory().getAbsolutePath()
     ordenFilePath = externalPath .. "/orden.txt"
     ordenFile = File(ordenFilePath)
    if not ordenFile.exists() then
        ordenFile.createNewFile()
    end
     outputStream = FileOutputStream(ordenFile)
    for i, fileData in ipairs(soundFilePaths) do
         line = fileData.filePath .. "," .. fileData.displayName .. "\n"
        for j = 1, #line do
            outputStream.write(string.byte(line, j))
        end
    end
    outputStream.close()
end
--marcador de dlg
 function combineFiles2()
 combinedFileName = "audio"
     combinedFileExtension = ".wav" 
     combinedFilePath = soundFolderPath .. combinedFileName .. combinedFileExtension
     combinedFile = io.open(combinedFilePath, "wb")
    if combinedFile then
        for i, fileData in ipairs(soundFilePaths) do
             soundFile = io.open(fileData.filePath, "rb")
            if soundFile then
                 data = soundFile:read("*a")
                combinedFile:write(data)
                soundFile:close()
            else
service.asyncSpeak("Lỗi khi mở tệp:" .. fileData.filePath)
            end
        end
        combinedFile:close()
service.asyncSpeak("đã chuyển đổi")
        grid.adapter.clear()
        for i, fileData in ipairs(soundFilePaths) do
            grid.adapter.add(fileData.displayName)
        end
        grid.adapter.notifyDataSetChanged()
        guardarOrden() -- Guardar el nuevo orden
        cargarOrden()
        cargarArchivos()
    else
service.asyncSpeak("không thể chuyển đổi")
    end
end
 function combineFiles3()
combinedFileName = "audio"
     combinedFileExtension = ".m4a" 
     combinedFilePath = soundFolderPath .. combinedFileName .. combinedFileExtension
     combinedFile = io.open(combinedFilePath, "wb")
    if combinedFile then
        for i, fileData in ipairs(soundFilePaths) do
             soundFile = io.open(fileData.filePath, "rb")
            if soundFile then
                 data = soundFile:read("*a")
                combinedFile:write(data)
                soundFile:close()
            else
service.asyncSpeak("Lỗi khi mở tệp:" .. fileData.filePath)
            end
        end
        combinedFile:close()
service.asyncSpeak("đã chuyển đổi")
        grid.adapter.clear()
        for i, fileData in ipairs(soundFilePaths) do
            grid.adapter.add(fileData.displayName)
        end
        grid.adapter.notifyDataSetChanged()
        guardarOrden() -- Guardar el nuevo orden
        cargarOrden()
        cargarArchivos()
    else
service.asyncSpeak("không thể chuyển đổi")
    end
end
 function combineFiles4()
combinedFileName = "audio"
     combinedFileExtension = ".aac" 
     combinedFilePath = soundFolderPath .. combinedFileName .. combinedFileExtension
     combinedFile = io.open(combinedFilePath, "wb")
    if combinedFile then
        for i, fileData in ipairs(soundFilePaths) do
             soundFile = io.open(fileData.filePath, "rb")
            if soundFile then
                 data = soundFile:read("*a")
                combinedFile:write(data)
                soundFile:close()
            else
service.asyncSpeak("Lỗi khi mở tệp:" .. fileData.filePath)
            end
        end
        combinedFile:close()
service.asyncSpeak("đã chuyển đổi")
        -- Actualizar la vista de la lista
        grid.adapter.clear()
        for i, fileData in ipairs(soundFilePaths) do
            grid.adapter.add(fileData.displayName)
        end
        grid.adapter.notifyDataSetChanged()
        guardarOrden() -- Guardar el nuevo orden
        cargarOrden()
        cargarArchivos()
    else
service.asyncSpeak("không thể chuyển đổi")
    end
end
 function combineFiles5()
combinedFileName = "audio"
     combinedFileExtension = ".ogg" 
     combinedFilePath = soundFolderPath .. combinedFileName .. combinedFileExtension
     combinedFile = io.open(combinedFilePath, "wb")
    if combinedFile then
        for i, fileData in ipairs(soundFilePaths) do
             soundFile = io.open(fileData.filePath, "rb")
            if soundFile then
                 data = soundFile:read("*a")
                combinedFile:write(data)
                soundFile:close()
            else
service.asyncSpeak("Lỗi khi mở tệp:" .. fileData.filePath)
            end
        end
        combinedFile:close()
service.asyncSpeak("đã chuyển đổi")
        -- Actualizar la vista de la lista
        grid.adapter.clear()
        for i, fileData in ipairs(soundFilePaths) do
            grid.adapter.add(fileData.displayName)
        end
        grid.adapter.notifyDataSetChanged()
        guardarOrden() -- Guardar el nuevo orden
        cargarOrden()
        cargarArchivos()
    else
service.asyncSpeak("không thể chuyển đổi")
    end
end
function combineFiles6()
combinedFileName = "video"
combinedFileExtension = ".mp4"
combinedFilePath = soundFolderPath .. combinedFileName .. combinedFileExtension
combinedFile = io.open(combinedFilePath, "wb")
if combinedFile then
for i, fileData in ipairs(soundFilePaths) do
soundFile = io.open(fileData.filePath, "rb")
if soundFile then
data = soundFile:read("*a")
combinedFile:write(data)
soundFile:close()
else
service.asyncSpeak("Lỗi khi mở tệp:" .. fileData.filePath)
end
end
combinedFile:close()
service.asyncSpeak("đã chuyển đổi")
grid.adapter.clear()
for i, fileData in ipairs(soundFilePaths) do
grid.adapter.add(fileData.displayName)
end
grid.adapter.notifyDataSetChanged()
guardarOrden() -- Guardar el nuevo orden
cargarOrden()
cargarArchivos()
else
service.asyncSpeak("không thể chuyển đổi")
end
end--marcador de dlg
layout = {
    LinearLayout,
    orientation = LinearLayout.VERTICAL,
    {
        TextView,
        text = "chuyển đổi định dạng âm thanh",
        textSize = "20sp",
        gravity = "center",
        padding = "16dp",
    },
    {
        GridView,
        id = "grid",
        numColumns = 1,
        layout_width = "fill",
        layout_height = "fill"
    },
{
Button,
id = "btnCombineFiles",
text = "chuyển đổi sang mp3",
layout_weight = 1,
onClick = combineFiles
},
{
Button,
id = "btnCombineFiles2",
text = "chuyển đổi sang wav",
layout_weight = 1,
onClick = combineFiles2
},
{
Button,
id = "btnCombineFiles3",
text = "chuyển đổi sang m4a",
layout_weight = 1,
onClick = combineFiles3
},
{
Button,
id = "btnCombineFiles4",
text = "chuyển đổi sang aac",
layout_weight = 1,
onClick = combineFiles4
},
{
Button,
id = "btnCombineFiles5",
text = "chuyển đổi sang ogg",
layout_weight = 1,
onClick = combineFiles5
},
{Button,
id = "btnCombineFiles6",
text = "chuyển đổi sang mp4",
layout_weight = 1,
onClick = combineFiles6
},
    {
        Button,
        id = "btnDeleteItem",
        text = "xóa tất cả các tập tin",
        layout_weight = 1,
        onClick = deleteFiles
    },
{
Button,
id = "btncloseDialog",
text = "lưu và đóng tiện ích mở rộng này",
layout_weight = 1,
onClick = closeDialog
}
}
 mediaPlayer = MediaPlayer()
 isPlaying = false
 currentSoundFilePath = nil
--marcador reproductor
function playSound(soundFilePath)
    if currentSoundFilePath == soundFilePath then
        mediaPlayer.stop()
        mediaPlayer.reset()
        isPlaying = false
        currentSoundFilePath = nil
        return
    end
    if isPlaying then
        mediaPlayer.stop()
        mediaPlayer.reset()
    end
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC)
    mediaPlayer.setDataSource(soundFilePath)
    mediaPlayer.prepare()
    mediaPlayer.start()
    isPlaying = true
    currentSoundFilePath = soundFilePath
    for i, fileData in ipairs(soundFilePaths) do
        if fileData.filePath == soundFilePath then
            currentSoundIndex = i
            break
        end
    end
    mediaPlayer.setOnCompletionListener(MediaPlayer.OnCompletionListener {
        onCompletion = function(mp)
             nextPosition = currentSoundIndex + 1
            if nextPosition <= #soundFilePaths then
                 nextSoundFilePath = soundFilePaths[nextPosition].filePath
                playSound(nextSoundFilePath)
            end
        end
    })
end
--reproductor marcador
guardarOrden()
dlg = LuaDialog(service)
dlg.View = loadlayout(layout)
 adapterItems = {}
for i, fileData in ipairs(soundFilePaths) do
    table.insert(adapterItems, fileData.displayName)
end
grid.adapter = ArrayAdapter(service, android.R.layout.simple_list_item_1, adapterItems)
dlg.show()
grid.onItemClick = function(l, v, position, id)
    if not isLongPress then
        vibrator.vibrate(100)
         selectedSoundFilePath = soundFilePaths[position + 1].filePath
        playSound(selectedSoundFilePath)
    end
    isLongPress = false
end
grid.onItemLongClick = function(l, v, position, id)
    isLongPress = true
    vibrator.vibrate(100)
options = {"xoá", "chia sẻ", "đổi tên", "duy chuyển lên", "duy chuyển xuống"}
     dialog = LuaDialog(context)
dialog.setTitle("tùy chọn với file âm thanh hiện tại")
     layout = {
        LinearLayout,
        orientation = LinearLayout.VERTICAL,
        {
            Button,
            text = options[1],
            onClick = function(view)
                deleteItem(position)
                dialog.dismiss()
            end
        },
        {
            Button,
            text = options[2],
            onClick = function(view)
                shareFile(position)
                dialog.dismiss()
            end
        },
        {
            Button,
            text = options[3],
            onClick = function(view)
                renameItem(position)
                dialog.dismiss()
            end
        },
        {
            Button,
            text = options[4],
            onClick = function(view)
                subir(position)
                dialog.dismiss()
            end
        },
        {
            Button,
            text = options[5],
            onClick = function(view)
                bajar(position)
                dialog.dismiss()
            end
        }
    }

     contentView = loadlayout(layout)
    dialog.setView(contentView)
    dialog.setCancelable(true)
    dialog.show()

    return true
end
return true
elseif v.text == "máy nghe nhạc" then
require "import"
import "java.io.FileOutputStream"
import "java.io.OutputStreamWriter"
import "java.io.BufferedReader"
import "java.io.InputStreamReader"
import "java.io.File"
import "java.io.FileInputStream"
import "java.text.SimpleDateFormat"
import "java.util.Date"
import "android.content.ContentValues"
import "android.media.MediaMuxer"
import "android.media.MediaFormat"
import "android.content.*"
import "android.content.pm.PackageManager"

import "android.net.Uri"
import "android.view.View"
import "android.widget.*"
import "android.content.Intent"
import "android.media.MediaPlayer"
import "android.content.Context"
import "android.os.Vibrator"
import "java.lang.reflect.Array"
import "java.lang.System"
import "android.os.Environment"
import "android.media.AudioManager"
import "java.io.File"
import "android.os.Environment"
import "android.widget.ArrayAdapter"
import "android.content.Context"
import "android.os.Vibrator"
import "android.widget.*"
import "com.androlua.*"
 context = activity or service
 vibrator = context.getSystemService(Context.VIBRATOR_SERVICE)
vibrator.vibrate(100)
if isPlaying then
mediaPlayer.stop()
mediaPlayer.reset()
isPlaying = false
currentSoundFilePath = nil
end
--fin de bibliotecas
currentSoundIndex = 0
 folderPath = "/storage/emulated/0/YMusic"
 folder = File(folderPath)
if not folder.exists() then
 success = folder.mkdirs()
if success then
service.asyncSpeak("vui lòng chờ" .. folderPath)
else
service.asyncSpeak("không thể tạo thư mục trong bộ nhớ" .. folderPath)
end
end
 externalPath = Environment.getExternalStorageDirectory().getAbsolutePath()
 soundFolderPath = externalPath .. "/YMusic/"
 soundFolder = File(soundFolderPath)
 soundFiles = soundFolder.listFiles()
 soundFilePaths = {}
if soundFiles ~= nil then
     soundFileCount = Array.getLength(soundFiles)
    if soundFileCount > 0 then
         soundFileCreationTimes = {}
        for i = 0, soundFileCount - 1 do
             soundFile = soundFiles[i]
             soundFilePath = soundFile.getAbsolutePath()
             fileName = soundFile.getName()
             creationTime = soundFile.lastModified()
            table.insert(soundFileCreationTimes, { filePath = soundFilePath, displayName = fileName, creationTime = creationTime })
        end
        table.sort(soundFileCreationTimes, function(a, b)
            return a.creationTime < b.creationTime
        end)
        for i = 1, #soundFileCreationTimes do
             soundFile = soundFileCreationTimes[i]
            table.insert(soundFilePaths, { filePath = soundFile.filePath, displayName = soundFile.displayName })
        end
    else
service.asyncSpeak("thư mục trống! không có tệp âm thanh, vui lòng thêm vào trước khi chạy tiện ích mở rộng này" .. soundFolderPath)        return false
    end
else
    service.asyncSpeak("Không thể truy cập thư mục:" .. soundFolderPath)
    return false
end
function cargarArchivos()
  soundFilePaths = {}
  -- Obtener la lista de archivos en la carpeta
   soundFolderPath = externalPath .. "/YMusic/"
   soundFolder = File(soundFolderPath)
   soundFiles = soundFolder.listFiles()
  if soundFiles ~= nil then
     soundFileCount = Array.getLength(soundFiles)
    if soundFileCount > 0 then
       soundFileCreationTimes = {}
      for i = 0, soundFileCount - 1 do
         soundFile = soundFiles[i]
         soundFilePath = soundFile.getAbsolutePath()
         fileName = soundFile.getName()
         creationTime = soundFile.lastModified()
        table.insert(soundFileCreationTimes, { filePath = soundFilePath, displayName = fileName, creationTime = creationTime })
      end
      table.sort(soundFileCreationTimes, function(a, b)
        return a.creationTime < b.creationTime
      end)
      for i = 1, #soundFileCreationTimes do
         soundFile = soundFileCreationTimes[i]
        table.insert(soundFilePaths, { filePath = soundFile.filePath, displayName = soundFile.displayName })
      end
      list.adapter.clear()
      for i, fileData in ipairs(soundFilePaths) do
        list.adapter.add(fileData.displayName)
      end
      list.adapter.notifyDataSetChanged()
    else
      service.asyncSpeak("Không tìm thấy tệp âm thanh nào trong thư mục:" .. soundFolderPath)
    end
  else
    service.asyncSpeak("Không thể truy cập thư mục:" .. soundFolderPath)
  end
end

 function renameItem(position)
   fileData = soundFilePaths[position + 1]
   file = File(fileData.filePath)
   fileName, fileExtension = string.match(fileData.displayName, "(.-)(%.%w+)$") -- Obtener el nombre y la extensión del archivo
   renameDialog = LuaDialog(context)
  renameDialog.setTitle("Đổi tên tập tin")
   input = EditText(context)
  input.setText(fileName)
  renameDialog.setView(input)
  renameDialog.setPositiveButton("đồng ý", DialogInterface.OnClickListener {
    onClick = function(dialog, which)
       newFileName = tostring(input.getText())
       newFilePath = file.getParent() .. "/" .. newFileName .. fileExtension
       newFile = File(newFilePath)
      if file.renameTo(newFile) then
        fileData.displayName = newFileName .. fileExtension
        adapterItems[position + 1] = fileData -- Actualizar el elemento en adapterItems
        list.adapter.clear()
        for i, fileData in ipairs(soundFilePaths) do
          list.adapter.add(fileData.displayName)
        end
        list.adapter.notifyDataSetChanged()
        service.asyncSpeak("Đã đổi tên tệp thành công.")
        -- dlg.dismiss()
      else
        service.asyncSpeak("đã có lỗi xảy ra khi đổi tên file âm thanh")
      end
      vibrator.vibrate(100)
dialog.dismiss()
    end
  })
  renameDialog.setNegativeButton("hủy", DialogInterface.OnClickListener {
    onClick = function(dialog, which)
      vibrator.vibrate(100)
dialog.dismiss()
    end
  })
  renameDialog.show()
end
 function shareFile(position)
     selectedSoundFilePath = soundFilePaths[position + 1].filePath
    service.shareFile(selectedSoundFilePath)
dlg.dismiss()
end
 function deleteItem(position)
     fileData = soundFilePaths[position + 1]
     file = File(fileData.filePath)
     confirmationDialog = LuaDialog(context)
    confirmationDialog.setTitle("xóa tệp âm thanh")
    confirmationDialog.setMessage("bạn có chắc chắn xóa tệp âm thanh này khỏi danh sách không?")
    confirmationDialog.setPositiveButton("xóa", DialogInterface.OnClickListener {
        onClick = function(dialog, which)
            file.delete()
            table.remove(soundFilePaths, position + 1)
            service.asyncSpeak("đã xóa tệp âm thanh khỏi danh sách")
        end
    })
    confirmationDialog.setNegativeButton("hủy", DialogInterface.OnClickListener {
        onClick = function(dialog, which)
            vibrator.vibrate(100)
dialog.dismiss()
        end
    })
    confirmationDialog.show()
end
--marcador de dlg
--marcador de dlg
layout = {
    LinearLayout,
    orientation = LinearLayout.VERTICAL,
    {
        TextView,
        text = "máy nghe nhạc",
        textSize = "20sp",
        gravity = "center",
        padding = "16dp",
},
    {
        ListView,
        id = "list",
        layout_width = "fill",
        layout_height = "fill"
    }
}
mediaPlayer = MediaPlayer()
isPlaying = false
currentSoundFilePath = nil
function playSound(soundFilePath)
    if currentSoundFilePath == soundFilePath then
        mediaPlayer.stop()
        mediaPlayer.reset()
        isPlaying = false
        currentSoundFilePath = nil
        return
    end

    if isPlaying then
        mediaPlayer.stop()
        mediaPlayer.reset()
    end
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC)
    mediaPlayer.setDataSource(soundFilePath)
    mediaPlayer.prepare()
    mediaPlayer.start()
    isPlaying = true
    currentSoundFilePath = soundFilePath
    for i, fileData in ipairs(soundFilePaths) do
        if fileData.filePath == soundFilePath then
            currentSoundIndex = i
            break
        end
    end
    mediaPlayer.setOnCompletionListener(MediaPlayer.OnCompletionListener {
        onCompletion = function(mp)
             nextPosition = currentSoundIndex + 1
            if nextPosition <= #soundFilePaths then
                 nextSoundFilePath = soundFilePaths[nextPosition].filePath
                playSound(nextSoundFilePath)
            end
        end
    })
end
dlg = LuaDialog(service)
dlg.View = loadlayout(layout)
 adapterItems = {}
for i, fileData in ipairs(soundFilePaths) do
    table.insert(adapterItems, fileData.displayName)
end
list.adapter = ArrayAdapter(service, android.R.layout.simple_list_item_1, adapterItems)
dlg.show()
--marcador click simple
list.onItemClick = function(l, v, position, id)
        vibrator.vibrate(100)
         selectedSoundFilePath = soundFilePaths[position + 1].filePath
        playSound(selectedSoundFilePath)
    end
list.onItemLongClick = function(l, v, position, id)
    isLongPress = true
    vibrator.vibrate(100)
if isPlaying then
mediaPlayer.stop()
mediaPlayer.reset()
isPlaying = false
currentSoundFilePath = nil
end
options = {"xoá", "chia sẻ", "đổi tên", "tải lên", "tải xuống"}
     dialog = LuaDialog(context)
    dialog.setTitle("tùy chọn với file âm thanh hiện tại")
     layout = {
        LinearLayout,
        orientation = LinearLayout.VERTICAL,
        {
            Button,
            text = options[1],
            onClick = function(view)
                deleteItem(position)
                vibrator.vibrate(100)
dialog.dismiss()
            end
        },
        {
            Button,
            text = options[2],
            onClick = function(view)
                shareFile(position)
                vibrator.vibrate(100)
dialog.dismiss()
            end
        },
        {
            Button,
            text = options[3],
            onClick = function(view)
                renameItem(position)
                vibrator.vibrate(100)
dialog.dismiss()
            end
        }
    }
     contentView = loadlayout(layout)
    dialog.setView(contentView)
    dialog.setCancelable(true)
    dialog.show()
end
end
end)
end